package com.rndemo.rn.view;

import android.content.Context;
import android.support.annotation.NonNull;
import android.view.View;

import com.facebook.react.ReactApplication;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.SizeMonitoringFrameLayout;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewOperationDelegate;
import com.facebook.react.views.view.ReactViewGroup;

/**
 * Created by tzj on 2018/5/3.
 * todo 高度不能包裹自身
 */
public class RnFrameLayout extends SizeMonitoringFrameLayout implements ViewOperationDelegate {
    public RnFrameLayout(@NonNull Context context) {
        super(context);
        setMinimumHeight(60);//为了减少外层包裹的数量
    }

    private final Runnable measureAndLayout = new Runnable() {
        @Override
        public void run() {
            if (getWidth() > 0 && getHeight() > 0) {
                measure(
                        View.MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
                        MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
                layout(getLeft(), getTop(), getRight(),  getBottom());
            }
        }
    };

    @Override
    public void requestLayout() {
        super.requestLayout();
        post(measureAndLayout);
    }

    @Override
    protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) {
        //todo 子view 的大小问题
        if(child instanceof ReactViewGroup){
            int widthMode = View.MeasureSpec.getMode(parentWidthMeasureSpec);
            int heightMode = View.MeasureSpec.getMode(parentHeightMeasureSpec);
            if (widthMode == View.MeasureSpec.UNSPECIFIED) {
                parentWidthMeasureSpec = MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(), MeasureSpec.EXACTLY);
            }
            if(heightMode == View.MeasureSpec.UNSPECIFIED){
                parentHeightMeasureSpec = MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(), MeasureSpec.EXACTLY);
            }
        }
        super.measureChildWithMargins(child,parentWidthMeasureSpec,widthUsed,parentHeightMeasureSpec,heightUsed);
    }

    @Override
    public boolean intercept() {
        return true;
    }

    public void addReactView(final View view){
        setOnSizeChangedListener(new OnSizeChangedListener() {
            @Override
            public void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
                setReactChildSize(view);
            }
        });
        addView(view);
    }

    private void setReactChildSize(final View child){
        Context applicationContext = getContext().getApplicationContext();
        if (applicationContext instanceof ReactApplication) {
            ReactContext currentReactContext = ((ReactApplication) applicationContext).getReactNativeHost().getReactInstanceManager().getCurrentReactContext();
            if (currentReactContext != null) {
                final UIManagerModule nativeModule = currentReactContext.getNativeModule(UIManagerModule.class);
                currentReactContext.runOnNativeModulesQueueThread(new Runnable() {
                    @Override
                    public void run() {
                        nativeModule.updateNodeSize(child.getId(),getWidth(),getHeight());
                    }
                });
            }
        }
    }

}
